package com.zx.notification.admin.service.impl;

import com.zx.core.enums.StatusEnum;
import com.zx.core.page.PageInfo;
import com.zx.core.wrapper.ObjectWrapper;
import com.zx.core.wrapper.PageWrapper;
import com.zx.core.wrapper.ResponseWrapper;
import com.zx.notification.admin.service.INotificationTemplatesService;
import com.zx.notification.common.dao.NotificationTemplatesMapper;
import com.zx.notification.common.enums.BizTypeEnum;
import com.zx.notification.common.enums.ChannelTypeEnum;
import com.zx.notification.common.enums.ConsumeModeEnum;
import com.zx.notification.common.mapstruct.NotificationTemplatesMapStructMapper;
import com.zx.notification.common.model.NotificationTemplates;
import com.zx.notification.common.param.NotificationTemplatesParam;
import com.zx.notification.common.service.ConfigChangeListener;
import com.zx.notification.common.utils.NotificationNoUtils;
import com.zx.notification.common.vo.NotificationTemplatesVO;
import com.zx.security.block.uitls.SecurityUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * description: 通知模板管理服务实现类 <br>
 * create: 2025-10-17
 * </p>
 *
 * @author zhou  xun
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class NotificationTemplatesServiceImpl implements INotificationTemplatesService {

    private final NotificationTemplatesMapper notificationTemplatesMapper;
    private final ConfigChangeListener configChangeListener;
    private final NotificationTemplatesMapStructMapper notificationTemplatesMapStructMapper;

    @Override
    public PageWrapper<NotificationTemplatesVO> getNotificationTemplatesVOListByPage(NotificationTemplatesParam notificationTemplatesParam) {
        PageWrapper<NotificationTemplatesVO> result = new PageWrapper<>();
        try {
            PageInfo pageInfo = new PageInfo(notificationTemplatesParam.getPageNum(), notificationTemplatesParam.getPageSize());
            notificationTemplatesParam.setPageNum(pageInfo.getPageNum());
            notificationTemplatesParam.setPageSize(pageInfo.getPageSize());

            // 查询总数
            Long count = notificationTemplatesMapper.getNotificationTemplatesListCount(notificationTemplatesParam.getTemplateCode(),
                    notificationTemplatesParam.getTemplateName(),
                    notificationTemplatesParam.getBizType(),
                    notificationTemplatesParam.getStatus(),
                    notificationTemplatesParam.getCreateTimeStart(),
                    notificationTemplatesParam.getCreateTimeEnd());
            if (count > 0) {

                // 分页查询列表
                List<NotificationTemplates> notificationTemplatesList = notificationTemplatesMapper.getNotificationTemplatesListByPage(
                        notificationTemplatesParam.getTemplateCode(),
                        notificationTemplatesParam.getTemplateName(),
                        notificationTemplatesParam.getBizType(),
                        notificationTemplatesParam.getStatus(),
                        notificationTemplatesParam.getCreateTimeStart(),
                        notificationTemplatesParam.getCreateTimeEnd(),
                        notificationTemplatesParam.getPageNum(),
                        notificationTemplatesParam.getPageSize());


                List<NotificationTemplatesVO> list = notificationTemplatesList.stream()
                        .map(notificationTemplatesMapStructMapper::notificationTemplatesToNotificationTemplatesVO)
                        .toList();

                // 设置返回结果
                result.setData(list);
            }
            result.setTotal(count);
            result.setCurrentPageNum(notificationTemplatesParam.getPageNum());
            result.setTotalPage(pageInfo);
        } catch (Exception e) {
            log.error("获取通知模板列表时发生错误", e);
            result.fail("获取通知模板列表失败，请稍后重试");
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper addNotificationTemplate(NotificationTemplatesParam notificationTemplatesParam) {
        ResponseWrapper result = new ResponseWrapper();

        try {
            // 验证参数
            ResponseWrapper validateResult = validateNotificationTemplateParams(notificationTemplatesParam, true);
            if (validateResult.verifyFail()) {
                return validateResult;
            }

            // 验证模板编码唯一性
            NotificationTemplates existingTemplate = notificationTemplatesMapper.selectByTemplateCode(notificationTemplatesParam.getTemplateCode());
            if (existingTemplate != null) {
                result.fail("模板编码已存在");
                return result;
            }

            // 创建通知模板对象
            NotificationTemplates notificationTemplates = notificationTemplatesMapStructMapper.notificationTemplatesParamToNotificationTemplates(notificationTemplatesParam);
            notificationTemplates.setId(NotificationNoUtils.generateNotificationId());

            // 设置创建信息
            notificationTemplates.setCreateBy(SecurityUtils.getUserId());
            notificationTemplates.setCreateTime(LocalDateTime.now());

            // 插入通知模板到数据库
            notificationTemplatesMapper.insertSelective(notificationTemplates);

            // 发布模板配置变更事件，触发缓存清理
            configChangeListener.publishConfigChange("template", "template_code:" + notificationTemplates.getTemplateCode());
        } catch (Exception e) {
            log.error("添加通知模板时发生错误", e);
            result.fail("添加通知模板失败: " + e.getMessage());
            // 重新抛出异常以触发事务回滚
            throw e;
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper editNotificationTemplate(NotificationTemplatesParam notificationTemplatesParam) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            // 验证参数
            ResponseWrapper validateResult = validateNotificationTemplateParams(notificationTemplatesParam, false);
            if (validateResult.verifyFail()) {
                return validateResult;
            }

            // 验证通知模板是否存在
            NotificationTemplates existingNotificationTemplate = notificationTemplatesMapper.selectByPrimaryKey(notificationTemplatesParam.getId());
            if (null == existingNotificationTemplate) {
                result.fail("通知模板不存在");
                return result;
            }

            // 验证模板编码唯一性（如果编码有变更）
            if (!existingNotificationTemplate.getTemplateCode().equals(notificationTemplatesParam.getTemplateCode())) {
                NotificationTemplates templateWithSameCode = notificationTemplatesMapper.selectByTemplateCode(notificationTemplatesParam.getTemplateCode());
                if (templateWithSameCode != null) {
                    result.fail("模板编码已存在");
                    return result;
                }
            }

            // 更新通知模板信息
            NotificationTemplates notificationTemplateToUpdate = notificationTemplatesMapStructMapper.notificationTemplatesParamToNotificationTemplates(notificationTemplatesParam);
            notificationTemplateToUpdate.setUpdateBy(SecurityUtils.getUserId());
            notificationTemplateToUpdate.setUpdateTime(LocalDateTime.now());
            notificationTemplatesMapper.updateByPrimaryKeySelective(notificationTemplateToUpdate);

            // 发布模板配置变更事件，触发缓存清理
            configChangeListener.publishConfigChange("template", "template_code:" + existingNotificationTemplate.getTemplateCode());
        } catch (Exception e) {
            log.error("编辑通知模板时发生错误", e);
            result.fail("编辑通知模板失败: " + e.getMessage());
            // 重新抛出异常以触发事务回滚
            throw e;
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper deleteNotificationTemplate(String notificationTemplateId) {
        ResponseWrapper result = new ResponseWrapper();

        try {
            // 验证通知模板是否存在
            NotificationTemplates existingNotificationTemplate = notificationTemplatesMapper.selectByPrimaryKey(notificationTemplateId);
            if (null == existingNotificationTemplate) {
                result.fail("通知模板不存在");
                return result;
            }

            // 删除通知模板
            notificationTemplatesMapper.deleteByPrimaryKey(notificationTemplateId);

            // 发布模板配置变更事件，触发缓存清理
            configChangeListener.publishConfigChange("template", "template_code:" + existingNotificationTemplate.getTemplateCode());
        } catch (Exception e) {
            log.error("删除通知模板时发生系统错误", e);
            result.fail("删除通知模板失败: " + e.getMessage());
            throw e; // 重新抛出异常以触发事务回滚
        }

        return result;
    }

    @Override
    public ObjectWrapper<NotificationTemplatesVO> selectNotificationTemplateById(String notificationTemplateId) {
        ObjectWrapper<NotificationTemplatesVO> result = new ObjectWrapper<>();
        try {
            // 验证通知模板是否存在
            NotificationTemplates selectByPrimaryKey = notificationTemplatesMapper.selectByPrimaryKey(notificationTemplateId);
            if (null == selectByPrimaryKey) {
                result.fail("通知模板不存在");
                return result;
            }

            NotificationTemplatesVO notificationTemplatesVO = notificationTemplatesMapStructMapper.notificationTemplatesToNotificationTemplatesVO(selectByPrimaryKey);
            result.setData(notificationTemplatesVO);
        } catch (Exception e) {
            log.error("获取通知模板信息时发生错误", e);
            result.fail("获取通知模板信息失败，请稍后重试");
        }

        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseWrapper updateNotificationTemplateStatus(NotificationTemplatesParam notificationTemplatesParam) {
        ResponseWrapper result = new ResponseWrapper();
        try {
            // 验证通知模板是否存在
            NotificationTemplates existingNotificationTemplate = notificationTemplatesMapper.selectByPrimaryKey(notificationTemplatesParam.getId());
            if (null == existingNotificationTemplate) {
                result.fail("通知模板不存在");
                return result;
            }

            // 更新通知模板状态
            NotificationTemplates notificationTemplateToUpdate = new NotificationTemplates();
            notificationTemplateToUpdate.setId(notificationTemplatesParam.getId());
            notificationTemplateToUpdate.setStatus(notificationTemplatesParam.getStatus());
            notificationTemplateToUpdate.setUpdateBy(SecurityUtils.getUserId());
            notificationTemplateToUpdate.setUpdateTime(LocalDateTime.now());
            notificationTemplatesMapper.updateByPrimaryKeySelective(notificationTemplateToUpdate);

            // 发布模板配置变更事件，触发缓存清理
            NotificationTemplates template = notificationTemplatesMapper.selectByPrimaryKey(notificationTemplatesParam.getId());
            if (template != null) {
                configChangeListener.publishConfigChange("template", "template_code:" + template.getTemplateCode());
            }
        } catch (Exception e) {
            log.error("更新通知模板状态时发生错误", e);
            result.fail("更新通知模板状态失败: " + e.getMessage());
            throw e; // 重新抛出异常以触发事务回滚
        }

        return result;
    }

    /**
     * 验证通知模板参数
     *
     * @param notificationTemplatesParam 通知模板参数
     * @param isAdd                      是否为新增操作
     * @return 验证结果
     */
    private ResponseWrapper validateNotificationTemplateParams(NotificationTemplatesParam notificationTemplatesParam, boolean isAdd) {
        ResponseWrapper result = new ResponseWrapper();

        // 新增时校验必填字段
        if (isAdd) {
            if (null == notificationTemplatesParam.getTemplateCode() || notificationTemplatesParam.getTemplateCode().isEmpty()) {
                result.fail("模板编码不能为空");
                return result;
            }

            if (null == notificationTemplatesParam.getTemplateName() || notificationTemplatesParam.getTemplateName().isEmpty()) {
                result.fail("模板名称不能为空");
                return result;
            }

            if (null == notificationTemplatesParam.getBizType() || notificationTemplatesParam.getBizType().isEmpty()) {
                result.fail("业务类型不能为空");
                return result;
            }

            if (null == notificationTemplatesParam.getTemplateContent() || notificationTemplatesParam.getTemplateContent().isEmpty()) {
                result.fail("模板内容不能为空");
                return result;
            }

            if (null == notificationTemplatesParam.getSupportedChannels() || notificationTemplatesParam.getSupportedChannels().isEmpty()) {
                result.fail("支持渠道不能为空");
                return result;
            }

            if (null == notificationTemplatesParam.getConsumeMode() || notificationTemplatesParam.getConsumeMode().isEmpty()) {
                result.fail("消费模式不能为空");
                return result;
            }

            if (null == notificationTemplatesParam.getStatus()) {
                result.fail("状态不能为空");
                return result;
            }
        }

        // 校验业务类型
        if (null != notificationTemplatesParam.getBizType() && BizTypeEnum.getEnumByCode(notificationTemplatesParam.getBizType()) == null) {
            result.fail("业务类型不正确");
            return result;
        }

        // 校验支持渠道
        if (null != notificationTemplatesParam.getSupportedChannels()) {
            String[] channels = notificationTemplatesParam.getSupportedChannels().split(",");
            for (String channel : channels) {
                if (ChannelTypeEnum.getEnumByCode(channel) == null) {
                    result.fail("支持渠道不正确: " + channel);
                    return result;
                }
            }
        }

        // 校验消费模式
        if (null != notificationTemplatesParam.getConsumeMode() && ConsumeModeEnum.getEnumByCode(notificationTemplatesParam.getConsumeMode()) == null) {
            result.fail("消费模式不正确");
            return result;
        }

        // 校验状态
        if (null != notificationTemplatesParam.getStatus() && StatusEnum.getEnumByCode(notificationTemplatesParam.getStatus()) == null) {
            result.fail("状态不正确");
            return result;
        }

        return result;
    }
}